ZOSE Documentation

Table of Contents

Getting Started
Things You Should Know
Interaction 72 - Using Custom Scripts
Recommended Template
Commands - Custom
Commands - Default
Memory Addresses
Credits

Getting Started

Welcome to the exciting world of scripting in the Zelda Oracles games. Currently, ZOSE is only for Oracle of Ages due to the assembly hacks that get automatically added. To get started, you need to make sure you have ZOSE with an extended Oracle of Ages ROM (It should be 2MB). If your ROM is still 1MB, it means you haven't opened it in ZOLE yet. Once ZOSE is opened, open your ROM by going to File > Open ROM... and opening it. On the message that pops up, be sure to answer "Yes" if you are comfortable with losing an event. Answering "No" will disable the ability to actually use ZOSE.

Things You Should Know

  • There are several things you should keep in mind when working with ZOSE. The first thing is when you don't write a script properly, it only tells you there was a compile error. This is either because of an unknown command or improper arguments, be them to short or an improper hexadecimal number.
  • Second, the Decompile Interaction only works for some things. This is actually a gameboy instruction emulator that does exactly what the game does. Luckily, it works for interaction 72, but with other ones because of the game's memory, it's likely they won't work. Interaction 20 xx also works fine, because they too point directly to scripts. When decompiling interaction 72 and you get an unknown opcode (typically 0), it means a script does not exist for this interaction.
  • Third, there is limited space in bank 0C. A lot of data has been moved but a lot is needed for interaction 72 pointers. When you find space for the first interaction address, go before 33FDA or as far back as possible! More assembly will be added along the way, and you don't want to have your script header overwrote by code.
  • Fourth, you cannot have more than one type 72 interaction in one room if they both use the jump 3-byte command. Since the data is only loaded into the memory once, the next loading will overwrite the old one and the first interaction will malfunction. You can still have multiple 3-byte jumps in one interaction though.
  • Fifth, the interaction will remain an invisible 8x8 tile where it was last positioned. It it recommended the interaction is moved to either 0, 0 or some other place that is not normally walkable.
  • Sixth, DO NOT place a script that uses a 3-byte jump underwater! It will not work!
  • Seventh, most commands don't actually get executed and take effect until the room has finished transitioning.
  • Finally, keep note that when jumping to a 3-byte address, chunks from there on that compile to more than 256 bytes will NOT work after the 256th byte. This is because only 256 bytes of scripting is read into the memory on the 3-byte jump, so anything beyond that won't be read. This can be solved by just finding more free space and jumping to that where the script continues. Do not worry about the space a script takes up though, because when compiling ZOSE will notify you if the space required is greater than 256 bytes.

Interaction 72 - Using Custom Scripts

You may be wondering how to actually use scripts. Before applying some assembly hacks, it was actually impossible to use ZOSE for anything other than interaction 20 and other ones that could successfully be decompiled. However, after said hacks were applied, a new interaction, type 72, was born, which allowed us direct pointing to scripts. These typically have a "header" in bank 0C, which is 5 bytes long, that points anywhere else in the ROM. Interaction 72 only has the pointer space to go up to about 240, but the space limitations in bank 0C leave us with maybe 40. You can however overwrite existing scripts, but it is not recommended if you cannot distinguish scripts between code.

To actually use a script, first open the ROM in ZOLE, navigate to the room which you want a script in. Add a type 1, 2, or 9 interaction. It is recommended to use a type 2 interaction because of the defined coordinates and the extra data in type 9 may not be used, but they all share the same ID system so it's up to you. Once the interaction is added, the ID will 72xx. The xx is the index and can go from FF-F0 (I recommend not going higher than DD for safe-keeps because of the pointer limitations. I'm not sure how many there are). In ZOSE, when writing the script, you will use the command setinteraction72 xx, which will make it so 72xx will execute the script. You'll see the full thing to do in the template.

Recommended Template

Many people would probably waste space and do the improper thing when writing scripts. To optimize space, it is highly recommend you start with this code, replacing (x) with what should go there.

writelocation (An address in bank 0C with atleast 5 bytes of free space)
setinteraction72 (The second half of your interaction)
jump3byte (Some place in the ROM with 256 bytes free outside of bank 00 and 0C)

writelocation (The same value the jump3byte had)
(Your actual script here

Commands - Custom

Please note none of the commands are case-sensitive. By default, all command arguments are hexadecimal numbers (All bytes unless stated otherwise) without the leading 0x or $.

Opcode

Command

Description

Args Length

Arguments

None

WriteLocation

Sets the address to compile the script to. This can be anywhere.

1

Compile Address

D5

CheckTile

Holds the script if the tile at the location does not match the specified tile.

2

Tile position (YX), Tile

E0

MakeTorchesLightable

Creates a bank 15 assembly procedure call making torches lightable.

0

None

E0

CreatePuffNoDelay

Creates a puff without holding up the script.

0

None

FF 02

CheckTile

Jumps if the tile at the location matches the specified tile.

3

Tile position (YX), Tile, Jump address

None

SetInteraction72

Sets the script address of interaction 72xx to the current compile location.

1

Interaction 72 index

00

ForceEnd

Forces the script to end.

0

None

FF 00

Jump3Byte

Jumps to anywhere in the ROM.

1

Jump address

FF 01

JumpRoomFlag

Jumps to anywhere in the ROM if the specified room flags are set.

2

Room flags, Jump address

FF 02

Jump3ByteMC

Jumps to anywhere in the ROM if a specified byte in the memory matches.

3

Memory address, Byte, Jump address

FF 03

JumpRoomFlagO

Jumps to anywhere in the ROM if the flags in a specified room are set.

4

Map, Group, Flags, Jump address

FF 04

UnsetRoomFlag

Unsets the specified room flag of the specified room.

3

Bit index, Map, Group

Commands - Default

Please note none of the commands are c ase-sensitive. By default, all command arguments are hexadecimal numbers (All bytes unless stated otherwise) without the leading 0x or $.

Opcode

Command

Description

Args Length

Arguments

01-7F

Jump2Byte

Jumps to a memory address with bank 0C active (Jumps to x in bank 0C)

1

Jump address (int)

80

SetVisible

Sets the interaction's Dx44 value.

1

Value

81

Set45

Sets the interaction's Dx45 value.

1

Value

83

Load100

Loads 100 values into the RAM. The purpose is unknown.

3

Value, Value, Value

84

SpawnCommon

Spawns a type 2 interaction.

4

ID1, ID2, Y, X

85

SpawnEnemy

Spawns a type 7 interaction.

4

ID1, ID2, Y, X

86

ShowPasswordScreen

Shows the password screen, most likely with the specified password.

1

Password?

87

LoadRel

Unknown real purpose.

2

Pointer1, Pointer2

88

SetCoords

Sets the interaction's coordinates.

2

Y, X

89

Set49

Sets the interaction's Dx49 value.

1

Value

8D

LoadD6667

Loads one byte into Dx66 and another into Dx67.

2

66 Value, 67 Value

8E

SetInteractionFactor

Sets a byte in the interaction's range of 256 bytes (Dx**).

2

Address LB, Value

8F

LoadSprite

Sets interaction's sprite value.

1

Value

90

CheckLinkXToMA

Check and compare Link's X to the interaction's X and write result to DxMA.

1

Address LB

91

SetMemory

Writes a value to the specified memory address.

2

Address (short), Value

92

ORMemory

ORs a value at the specified memory address by a value and writes the result.

2

Address (short), Value

94

AddSetInteractionFactor

Adds a byte to a byte in the interaction's range of 256 bytes (Dx**).

2

Address LB, Value

96

Set49Extra

Sets the interaction's Dx49 value and does another assembly procedure.

1

Value

97

SetTextIDJP

Sets the interaction's text ID and jumps to script 305F0.

2

Value1, Value2

98

ShowText

Shows the specified text ID.

2

Value1, Value2

99

CheckText

Holds the script if text is open.

0

None

9C

SetTextID

Sets the interaction's text ID.

2

Value1, Value2

9D

ShowLoadedText

Shows the interaction's text ID.

0

None

9E

CheckAButton

Checks to see if the A button is being pressed; doesn't work for all interactions.

0

None

B0

CheckRoomFlag

ANDs the room's flag by a certain value. Skips next command if set.

1

Value

B1

SetRoomFlag

ORs the room's flag by a certain value.

1

Value

B6

SetGlobalFlag

Sets a global flag in the format of a global flag.

1

Value

BD

DisableInput

Disables user input.

0

None

BE

EnableInput

Enables user input.

0

None

C0

CallScript

Calls a script.

1

Bank 0C script (short)

CD

CheckItemFlag

Checks the room's item flag, and if it's set, the script holds until it's not.

0

None

CF

CheckSpecialFlag

Checks the room's flag, and if the 7th bit is set, it holds until it's not.

0

None

D2

CheckEnemyCount

Checks the enemy count and holds the script until it's 0.

0

None

D3

CheckMemoryBit

Checks a memory bit and holds the script until it's set.

2

Bit, Address (short)

D5

CheckMemory

Holds the script if the byte at the supplied address does not match the value.

2

Address (short), Value

DD

SpawnItem

Spawns an item at the interaction's location with the same ID format as chests.

2

ID1, ID2

DE

GiveItem

Makes Link acquire the specified item with same ID format as chests.

2

ID1, ID2

E0

ASM15

Calls an assembly procedure in bank 15.

1

Address (short)

E2

CreatePuff

Creates a puff at the interaction's location and holds up the script.

0

None

E3

PlaySound

Plays the given sound or music.

1

Value

E4

SetMusic

Sets the music to the specified sound or music.

1

Value

E5

SetCC8A

Sets the byte at CC8A to the specified value.

1

Value

E6

SpawnEnemyHere

Spawns a type 7 interaction at the interaction's coordinates.

2

ID1, ID2

E7

SetTilePos

When the room has transitioned, sets the tile at the specified coordinates.

2

YX, Tile

E8

SetTile

When the room has transitioned, sets the tile at the interaction's coordinates.

1

Value

EA

ShakeScreen

Shakes the screen for the delay given (1 Second = 3C, or 60 in decimal)

1

Value

F0-FC

SetDelay*

* is a number from 0-12. Sets a delay of the script with defined times.

0

None

Memory Addresses

Here are some memory addresses that may or may not aid in script creating.

Address

Definition

Format

CC29

Buttons being pressed

1 Bit for each button

CC2A

The buttons that have been pressed (only pressed) on the current cycle

1 Bit for each button

C622

A cycle counter.

A simple byte. Goes up about 0x40 (64) times a second.

C688

B Weapon

Weapon ID

C689

A Weapon

Weapon ID

C6C4

Selected Seed Satchel seed

Seed

C6C5

Select Seed Shooter seed

Seed

C69E

Seeds the player has

1 Bit for each seed

CD02

Last map transition direction (00 = Up, 01 = Right, 02 = Down, 03 = Left)

Map transition

CC30

Current map

The current map the player is on

CC2D

Current map group

The current map group the player is on

CCA0

Triggers currently pressed

1 Bit for each trigger, or trigger index (Trigger ID: 09*x, x)

CC60

Link's sprite cannot change direction (holding a charge) if not 00

One byte

CC6C

Pegasus effect timer

Little-endian short extending into CC6D

CC63

Weapon action?

If FF, Link powerswings

CC8F

Count of lit torches

Count

CCAB

How long the wall lever is pulled out

Bit 7 set if pulled out all the way (clicked), rest is relative length

C6AA

Current health

00 = Dead, 40 = Full

C6AB

Max health

00 = Dead, 40 = Full

D00B

Link's Y position.

The absolute position.

D00D

Link's X position.

The absolute position.

D029

Damage being dealt to Link

If >= 80, decrease while < FF (For example, FD deals 2)

Credits

ZOSE created by Lin. Guide written by Lin. Thanks to Jigglysaint for guiding me in the direction of the game's scripting engine, providing a list of some opcodes, and helping where help was needed. Also thanks to him for an idea that massively improved ZOSE.